package com.uzhie.jt808.service.impl;

import com.uzhie.jt808.JT808Constant;
import com.uzhie.jt808.JT808Session;
import com.uzhie.jt808.msg.JT808MsgBean;
import com.uzhie.jt808.service.BaseService;
import com.uzhie.jt808.service.JT808DevManageService;
import com.uzhie.jt808.service.JT808PostService;
import com.uzhie.jt808.spring.MsgIDMapping;
import com.uzhie.jt808.spring.MsgService;
import com.uzhie.jt808.task.TaskCommonNotify;
import com.uzhie.jt808.util.ByteUtil;
import com.uzhie.jt808.util.JT808ProtocolUtil;
import com.uzhie.web.service.EquipmentService;
import com.uzhie.util.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

/**
 * Created by TangFei on 2018/7/17.
 * 终端管理类协议
 */
@MsgService(name = "devManage")
public class JT808DevManageServiceImpl extends BaseService implements JT808DevManageService {

    @Autowired(required = false)
    private EquipmentService equipmentService;

    @Autowired
    private CacheManager<String, byte[]> cacheManager;

    @Autowired
    private JT808PostService service;

    /**
     * 终端注册
     *
     * @param msgBean
     */
    @Override
    @MsgIDMapping(msgID = JT808Constant.MSG_ID.DEV_REQ_REGISTER)
    public JT808MsgBean register(JT808MsgBean msgBean) {
        // 响应指定应答
        byte[] bodyBytes;
        //  判断协议标准
        if (msgBean.getBodyBytes().length >= 26 && msgBean.getBodyBytes().length <= 38) {
            // 如果消息体长度为33 则为 808-2011 标准
            bodyBytes = register2011(msgBean);
        } else if (msgBean.getBodyBytes().length >= 38) {
            // 反之为 808-2013 标准
            bodyBytes = register2013(msgBean);
        } else {
            logger.error("未知设备");
            ByteBuffer byteBuffer = ByteBuffer.allocate(3);
            byteBuffer.put(JT808ProtocolUtil.parseInt2Word(msgBean.getHeader().getFlowNum()));
            byteBuffer.put(JT808ProtocolUtil.parseInt2Byte(4));
            bodyBytes = byteBuffer.array();
        }
        return super.build808Obj(JT808Constant.MSG_ID.PLA_RES_REGISTER, sysCache.getPlaFlowNum(), msgBean.getHeader().getSimNum(), bodyBytes);
    }

    /**
     * 808-2011 注册
     *
     * @param msgBean
     * @return 消息体 byte[]
     */
    private byte[] register2011(JT808MsgBean msgBean) {
        logger.trace("当前设备执行 2011 标准");
        // 解析消息体中的属性
        int provinceID = JT808ProtocolUtil.parseWord2Int(msgBean.getBodyBytes(), 0);
        int cityID = JT808ProtocolUtil.parseWord2Int(msgBean.getBodyBytes(), 2);
        String makerID = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 4, 5);
        String devModel = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 9, 8);
        String devID = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 17, 7);
        int vehiclePlateColor = JT808ProtocolUtil.parseByte2Int(msgBean.getBodyBytes(), 24);
        byte[] flagBytes = new byte[msgBean.getBodyBytes().length - 25];
        System.arraycopy(msgBean.getBodyBytes(), 25, flagBytes, 0, flagBytes.length);
        String vehiclePlate = new String(flagBytes, JT808Constant.CHARSET);
        // TODO: 2018/7/17 实现注册的具体逻辑

        // 设置返回消息体
        int respBodyResult = 0;
        byte[] flowNumByte = JT808ProtocolUtil.parseInt2Word(msgBean.getHeader().getFlowNum());
        byte[] resultByte = JT808ProtocolUtil.parseInt2Byte(respBodyResult);
        byte[] respBytes = ByteUtil.concatAll(flowNumByte, resultByte);
        if (respBodyResult == 0) {
            // 设置鉴权码 暂定为 123
            String authCode = "123";
            byte[] authCodeBytes = authCode.getBytes(JT808Constant.CHARSET);
            respBytes = ByteUtil.concatAll(respBytes, authCodeBytes);

        }
        // 设置 session 并指定协议类型
        sessionManager.refreshSimSession(msgBean.getHeader().getSimNum(), msgBean.getChannelHandlerContext().channel(), JT808Session.PROTO.PROTO_2011);
        return respBytes;
    }

    /**
     * 808-2013 注册
     *
     * @param msgBean
     * @return 消息体 byte[]
     */
    private byte[] register2013(JT808MsgBean msgBean) {
        logger.trace("当前设备执行 2013 标准");
        // 解析消息体中的属性
        int provinceID = JT808ProtocolUtil.parseWord2Int(msgBean.getBodyBytes(), 0);
        int cityID = JT808ProtocolUtil.parseWord2Int(msgBean.getBodyBytes(), 2);
        String makerID = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 4, 5);
        String devModel = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 9, 20);
        String devID = JT808ProtocolUtil.parseByteN2String(msgBean.getBodyBytes(), 29, 7);
        int vehiclePlateColor = JT808ProtocolUtil.parseByte2Int(msgBean.getBodyBytes(), 36);
        byte[] flagBytes = new byte[msgBean.getHeader().getBodyLength() - 37];
        System.arraycopy(msgBean.getBodyBytes(), 25, flagBytes, 0, flagBytes.length);
        String vehiclePlate = new String(flagBytes, Charset.forName("gbk"));
        // TODO: 2018/7/17 实现注册的具体逻辑

        // 设置返回消息体
        int respBodyResult = 0;
        byte[] flowNumByte = JT808ProtocolUtil.parseInt2Word(msgBean.getHeader().getFlowNum());
        byte[] resultByte = JT808ProtocolUtil.parseInt2Byte(respBodyResult);
        byte[] respBytes = ByteUtil.concatAll(flowNumByte, resultByte);
        if (respBodyResult == 0) {
            // 设置鉴权码 暂定为 123
            String authCode = "123";
            byte[] authCodeBytes = authCode.getBytes(JT808Constant.CHARSET);
            respBytes = ByteUtil.concatAll(respBytes, authCodeBytes);
        }
        // 设置 session 并指定协议类型
        sessionManager.refreshSimSession(msgBean.getHeader().getSimNum(), msgBean.getChannelHandlerContext().channel(), JT808Session.PROTO.PROTO_2013);
        return respBytes;
    }

    /**
     * 注销
     *
     * @param msgBean
     * @return
     */
    @Override
    @MsgIDMapping(msgID = JT808Constant.MSG_ID.DEV_REQ_UNREGISTER)
    public JT808MsgBean unregister(JT808MsgBean msgBean) {

        return null;
    }

    /**
     * 鉴权
     *
     * @param msgBean
     * @return
     */
    @Override
    @MsgIDMapping(msgID = JT808Constant.MSG_ID.DEV_REQ_AUTHEN)
    public JT808MsgBean authentication(JT808MsgBean msgBean) {
        // 响应通用应答
        byte[] bodyBytes;
        String authCode = new String(msgBean.getBodyBytes(), JT808Constant.CHARSET);
        logger.trace("平台收到鉴权码：" + authCode);
        if (equipmentService.simExist(msgBean.getHeader().getSimNum())) {
            logger.trace("鉴权成功");
            // 鉴权成功
            bodyBytes = super.commonRespBodyBytes(msgBean.getHeader().getFlowNum(), msgBean.getHeader().getMsgID(), 0);
        } else {
            logger.trace("鉴权失败");
            // 鉴权失败
            bodyBytes = super.commonRespBodyBytes(msgBean.getHeader().getFlowNum(), msgBean.getHeader().getMsgID(), 1);
        }
        return super.build808Obj(JT808Constant.MSG_ID.PLA_RES_COMMON, sysCache.getPlaFlowNum(), msgBean.getHeader().getSimNum(), bodyBytes);
    }

    /**
     * 设置终端参数
     *
     * @param msgBean
     * @return
     */
    @Override
    public JT808MsgBean setParam(JT808MsgBean msgBean) {

        return null;
    }

    /**
     * 查询终端参数
     *
     * @param msgBean
     * @return
     */
    @Override
    public JT808MsgBean queryParam(JT808MsgBean msgBean) {

        return null;
    }

    /**
     * 终端控制
     *
     * @param msgBean
     * @return
     */
    @Override
    public JT808MsgBean control(JT808MsgBean msgBean) {

        return null;
    }

    /**
     * 终端心跳
     *
     * @param msgBean
     * @return
     */
    @Override
    @MsgIDMapping(msgID = JT808Constant.MSG_ID.DEV_REQ_HEART_BEAT)
    public JT808MsgBean heartbeat(JT808MsgBean msgBean) {
        logger.info("808 心跳处理 " + msgBean.getChannelHandlerContext());
        refreshSession(msgBean);
        // 终端心跳 响应通用应答
        byte[] bodyBytes = super.commonRespBodyBytes(msgBean.getHeader().getFlowNum(), msgBean.getHeader().getMsgID(), 0);
        return super.build808Obj(JT808Constant.MSG_ID.PLA_RES_COMMON, sysCache.getPlaFlowNum(), msgBean.getHeader().getSimNum(), bodyBytes);
    }

    @MsgIDMapping(msgID = JT808Constant.MSG_ID.DEV_RES_COMMON)
    @Override
    public JT808MsgBean devCommonResp(JT808MsgBean msgBean) {
        byte[] respBytes = msgBean.getBodyBytes();
        int respMsgID = JT808ProtocolUtil.parseWord2Int(respBytes, 2);
        if (service.needReturn(respMsgID)) {
            int respFlowNum = JT808ProtocolUtil.parseWord2Int(respBytes, 0);
            // 生成 key
            StringBuilder lockBuild = new StringBuilder("POST_");
            lockBuild.append(msgBean.getHeader().getSimNum()).append("_").append(respMsgID).append("_").append(respFlowNum);
            // 存入 key - 终端响应结果
            cacheManager.put(CacheManager.DES.SYS_CACHE, lockBuild.toString(), msgBean.getBodyBytes());
            // 获取 key - 对象锁
            Thread lockThread = (Thread) sysCache.getCacheVal(lockBuild.toString());
            // 通知 key - 对象锁
            taskExecutor.execute(new TaskCommonNotify(lockThread));
        }
        byte[] bodyBytes = super.commonRespBodyBytes(msgBean.getHeader().getFlowNum(), msgBean.getHeader().getMsgID(), 0);
        return super.build808Obj(JT808Constant.MSG_ID.PLA_RES_COMMON, sysCache.getPlaFlowNum(), msgBean.getHeader().getSimNum(), bodyBytes);
    }

}
